home *** CD-ROM | disk | FTP | other *** search
- .MODEL SMALL
-
- .CODE
-
- ;---------------------------------------------------------
- ; __LngStg - Convert long integer to string.
- ;
- ; Entry -
- ; DX,AX = Long integer.
- ; ES:DI points to area for string.
- ;---------------------------------------------------------
- Public __LngStg
- __LngStg Proc Near
-
- Push Bp
- Push Di ;BP+2
- Push Es ;BP
- Mov Bp,Sp
-
- Mov Si,Dx
- Test Dh,80h ;Negative coming in ?
- Jz __LngStg0 ;Nope.
- Not Dx
- Neg Ax
- Sbb Dx,-1
- __LngStg0:
- Sub Bx,Bx
- Push Bx ;Set end of string on stack.
- LongStg_Lp0:
- Push Si
- Push Dx
- Push Ax
- Mov Cx,0
- Mov Bx,10
- Call ___LDiv ;Long/10.
- Pop Bx
- Pop Cx
-
- Push Dx ;Save next number to use.
- Push Ax
- Push Cx ;Save old number.
- Push Bx
- Mov Cx,0
- Mov Bx,10
- Call ___LMul
- Mov Cx,Dx
- Mov Bx,Ax
- Pop Ax
- Pop Dx
- Call ___LSub ;Find the remainder.
- Mov Bx,Ax
- Pop Ax ;Get next number to use.
- Pop Dx
- Pop Si
- Add BL,'0'
- Push Bx ;Save another digit.
- Mov Bx,Ax
- Or Bx,Dx ;Result 0 yet ?
- Jnz LongStg_Lp0 ;Nope, so go back up.
- ;
- ; The number is broken down, so let's assemble a string.
- ;
- Mov Di,[Bp][2] ;Load ES:DI with destination.
- Mov Es,[Bp]
- Cld
- Test Si,8000h ;Negative ?
- Jz LongStg_Pos ;Nope, so jump.
- Mov AL,'-'
- Stosb ;Set minus sign into string.
- LongStg_Pos:
- LongStg_Lp1:
- Pop Ax
- Stosb
- Or Al,Al
- Jnz LongStg_Lp1
- Mov Sp,Bp
- Pop Es
- Pop Di
- Pop Bp
- Ret
-
- __LngStg Endp
-
-
- ;------------------------- LOW LEVEL MATH ROUTINES ------------------------
- ;
- ;--------------------------
- ; ___Ladd - Add DX,AX to CX,BX, return DX,AX
- ; ___LSub - Sub CX,BX from DX,AX return DX,AX
- ;--------------------------
- Public ___Ladd,___LSub
- ___LSub Proc Near
-
- Push Ax
- Mov Ax,0
- Sub Ax,Bx ;Negate CX,BX.
- Mov Bx,Ax
- Mov Ax,0
- Sbb Ax,Cx
- Mov Cx,Ax
- Pop Ax
- ___Ladd:
- Add Ax,Bx
- Adc Dx,Cx
- Ret
-
- ___LSub Endp
-
-
-
-
- ;--------------------------
- ; ___LMul - Long integer multiplier
- ;--------------------------
- Public ___LMul
- ___LMul Proc Near
-
- Push Si
- Push Di
- Push Bp
- Sub Bp,Bp
- ;
- ; Check signs
- ;
- Test Dh,80h ;Op A neg ?
- Jz ___LMul_PA
- Not Bp
- Mov Si,0
- Sub Si,Ax
- Mov Ax,Si
- Mov Si,0
- Sbb Si,Dx
- Mov Dx,Si
- ___LMul_PA:
- Test Ch,80h ;Op B neg ?
- Jz ___LMul_PB
- Not Bp
- Mov Si,0
- Sub Si,Bx
- Mov Bx,Si
- Mov Si,0
- Sbb Si,Cx
- Mov Cx,Si
- ___LMul_PB:
- Mov Si,Dx
- Mov Di,Ax
- Mul Bx
- Push Ax
- Push Dx
-
- Mov Ax,Si
- Mul Bx
- Pop Bx
- Add Ax,Bx
- Adc Dx,0
- Push Ax
- Mov Bx,Dx
-
- Mov Ax,Di
- Mul Cx
- Pop Di
- Add Di,Ax
- Push Di
- Mov Di,0
- Adc Bx,Dx
- Adc Di,0
-
- Mov Ax,Si
- Mul Cx
- Add Ax,Bx
- Adc Dx,Di
- Pop Cx
- Pop Bx
-
- Or Ax,Dx
- Mov Ax,Bx
- Mov Dx,Cx
- Pushf
- Test Bp,Bp
- Jz ___LMul_RP
- Mov Bx,0
- Sub Bx,Ax
- Mov Ax,Bx
- Mov Bx,0
- Sbb Bx,Dx
- Mov Dx,Bx
- ___LMul_RP:
- Popf
- Pop Bp
- Pop Di
- Pop Si
- Jz ___LMul_Dne
- Stc
- ___LMul_Dne:
- Ret
-
- ___LMul Endp
-
-
-
-
- ;--------------------------
- ; ___LDiv - Divide
- ;
- ; OpA = DX,AX (DX=msw)
- ; OpB = CX,BX (CX=msw)
- ;
- ; A/B -> Destination (DX,AX - DX=msw)
- ;--------------------------
- Public ___LDiv
- ___LDiv Proc Near
-
- Push Bp
- Sub Sp,4
- Mov Bp,Sp
- Mov [Bp],Cx
- Or Cx,Bx
- Jnz __LD0 ;Jump if operand B is not 0.
- Sub Ax,Ax ;If so, then return 0.
- Mov Dx,Ax
- Jmp __LD_Exit
- __LD0:
- Mov [Bp+2],Dx
- Or Dx,Ax
- Jnz __LD1 ;Jump if operand A is not 0.
- Jmp __LD_Exit
- __LD1:
- Mov Cx,[Bp]
- Mov Dx,[Bp+2]
- Mov Si,Dx
- Test Si,Si
- Jns __LD2 ;Jump if op A is positive.
- Not Dx
- Neg Ax
- Sbb Dx,-1
- __LD2:
- Xor Si,Cx
- Mov [BP],Si ;Save a sign flag.
- Sub Si,Si
- Test Ch,Ch
- Jns __LD3 ;Jump if op B is positive.
- Not Cx
- Neg Bx
- Sbb Cx,-1
- __LD3:
- Jnz __LD6
- Test Bx,Bx
- Js __LD6
- Mov Di,20h
- __LD4:
- Shl Ax,1
- Rcl Dx,1
- Rcl Si,1
- Cmp Si,Bx
- Jb __LD5
- Sub Si,Bx
- Inc Ax
- __LD5:
- Dec Di
- Jnz __LD4
- Sub Cx,Cx
- Mov Bx,Si
- Jmp __Lda
- __LD6:
- Mov Di,0010h
- __LD7:
- Shl Ax,1
- Rcl Dx,1
- Rcl Si,1
- Cmp Si,Cx
- Jb __LD9
- Jnz __LD8
- Cmp Dx,Bx
- Jb __LD9
- __LD8:
- Sub Dx,Bx
- Sbb Si,Cx
- Inc Ax
- __LD9:
- Dec Di
- Jnz __LD7
- Mov Cx,Si
- Mov Bx,Dx
- Sub Dx,Dx
- __LDA:
- Test Word Ptr [BP],8000h
- Jz __LDB
- Not Dx
- Neg Ax
- Sbb Dx,-1
- __LDB:
- Test Word Ptr [BP+2],8000h
- Jz __LD_Exit
- Not Cx
- Neg Bx
- Sbb Cx,-1
- __LD_Exit:
- Add Sp,4
- Pop Bp
- Ret
-
- ___LDiv Endp
-
-
- END